package ac.github.os.internal.core.condition.impl.player

import ac.github.os.internal.core.condition.Condition
import ac.github.os.internal.core.condition.call
import ac.github.os.internal.core.config.StringConfig
import ac.github.os.internal.core.config.get
import ac.github.os.internal.core.trigger.PlayerTrigger
import ac.github.os.internal.session.Session
import org.bukkit.Material
import org.bukkit.inventory.ItemStack
import taboolib.common.platform.Awake
import taboolib.common.platform.function.info
import taboolib.type.BukkitEquipment

abstract class ItemCondition : Condition {
    override fun doScreen(session: Session, config: StringConfig): Boolean {
        return session.call<PlayerTrigger> {
            val itemStack = BukkitEquipment.valueOf(config.get("type", "HAND")!!).getItem(it.player)
            run(session, config, itemStack)
        }
    }

    abstract fun run(session: Session, config: StringConfig, itemStack: ItemStack?): Boolean

    override val namespace: String
        get() = "item:$name"

    fun StringConfig.vague(): Boolean = get("vague", false)!!

    fun StringConfig.value(): String? = get<String>("val")

    abstract val name: String

}

@Awake
class ItemNull : ItemCondition() {
    override fun run(session: Session, config: StringConfig, itemStack: ItemStack?): Boolean {
        return itemStack == null
    }

    override val name: String
        get() = "null"
}

@Awake
class ItemNotNull : ItemCondition() {
    override fun run(session: Session, config: StringConfig, itemStack: ItemStack?): Boolean {
        return itemStack != null
    }

    override val name: String
        get() = "notnull"
}

@Awake
class ItemDisplayName : ItemCondition() {

    override fun run(session: Session, config: StringConfig, itemStack: ItemStack?): Boolean {
        val name = itemStack?.itemMeta?.displayName ?: "null"
        val value = config.value() ?: return false
        val vague = config.vague()
        return if (vague) name.contains(value ) else name == value
}

override val name: String
    get() = "name"

}

@Awake
class ItemMaterial : ItemCondition() {

    override fun run(session: Session, config: StringConfig, itemStack: ItemStack?): Boolean {
        val type = itemStack?.type ?: Material.AIR
        val value = config.value() ?: return false
        return if (config.vague()) type.name.contains(value) else type.name == value
    }

    override val name: String
        get() = "material"
}

@Awake
class ItemLoreHasKeyWord : ItemCondition() {
    override fun run(session: Session, config: StringConfig, itemStack: ItemStack?): Boolean {
        val value = config.value() ?: return false
        val list = itemStack?.itemMeta?.lore ?: arrayListOf()
        return if (config.vague()) list.any { it.contains(value) } else list.any { it == value }
    }

    override val name: String
        get() = "has-lore"
}